<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\ApiController;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Yansongda\Pay\Pay;
use Yansongda\Pay\Log;

class ShoppingMallController extends ApiController
{

    /**
     * 商城首页
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function index()
    {
        //广告轮播
        $ads = DB::table('ad')->where(['status' => 1])->select('name', 'pic', 'bind_type', 'bind_id')->take(5)->orderBy('weight', 'desc')->get();
        if (empty($ads)) {
            $ads = [];
        }

        //个性单品
        $goods = DB::table('goods')->where(['type' => 1, 'status' => 1])->select('id', 'title', 'main_pic', 'present_price')->take(6)->get();
        if (empty($goods)) {
            $goods = [];
        }
        return $this->success(['ads' => $ads, 'goods' => $goods]);
    }

    /**
     * 商品列表
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function goods(Request $request)
    {
        $type = $request->input("type", 1); //1单品 2套餐
        $group_type = $request->input("group_type", 1); //1减脂 2增肌
        $page = $request->input("page", 1);
        $limit = $request->input("limit", 10);
        if (!in_array($type, array(1, 2))) {
            return $this->failed("参数错误");
        }
        if ($limit > 100 || $limit < 0) {
            return $this->failed("参数错误");
        }
        $where = ['status' => 1, 'type' => $type];
        if ($type == 2) {
            if (!in_array($group_type, array(1, 2))) {
                return $this->failed("参数错误");
            }
            $where['group_type'] = $group_type;
        }

        $count = DB::table('goods')->where($where)->count();
        $goods = DB::table('goods')->select('id', 'title', 'desc', 'main_pic', 'present_price')->where($where)->skip($limit * ($page -1))->take($limit)->get();
        return $this->success(['goods' => $goods, 'more' => $count > $page * $limit ? true : false]);
    }

    /**
     * 商品详情
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function goodsInfo(Request $request)
    {
        $id = $request->input("id", 0);
        if ($id <= 0) {
            return $this->failed("参数错误");
        }
        $goods = DB::table('goods')->where(['id' => $id, 'status' => 1])->select('id', 'title', 'content', 'desc', 'all_pics', 'present_price', 'type', 'is_fresh')->first();
        if (empty($goods)) {
            return $this->failed("参数错误");
        }
        $goods->all_pics = json_decode($goods->all_pics);
        return $this->success(['goods' => $goods]);
    }

    /**
     * 添加到购物车
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function addToCart(Request $request)
    {
        $user = Auth::user();
        $user_id = $user->id;
        $id = $request->input("id", 0);
        if ($id <= 0) {
            return $this->failed("参数错误");
        }
        $goods = DB::table('goods')->where(['id' => $id, 'status' => 1])->first();
        if (empty($goods)) {
            return $this->failed("参数错误");
        }
        $goods_is_exist = DB::table('shopping_cart')->where(['user_id' => $user_id, 'goods_id' => $id])->first();
        if (!empty($goods_is_exist)) {
            $res = DB::table('shopping_cart')->where(['id' => $goods_is_exist->id])->increment('goods_num');
        } else {
            $res = DB::table('shopping_cart')->insert(['user_id' => $user_id, 'goods_id' => $id, 'goods_num' => 1, 'is_fresh' => $goods->is_fresh]);
        }
        if (empty($res)) {
            return $this->failed("添加到购物车失败");
        }
        return $this->success("添加到购物车成功");
    }

    /**
     * 购物车列表
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function cartList(Request $request)
    {
        $user = Auth::user();
        $user_id = $user->id;
        $is_fresh = $request->input("is_fresh", 0);
        if (!in_array($is_fresh, array(0, 1))) {
            return $this->failed("参数错误");
        }
        $cart_list = DB::table('shopping_cart AS c')
            ->leftJoin('goods AS g', 'g.id', '=', 'c.goods_id')
            ->select('c.goods_id', 'c.goods_num', 'g.title', 'g.main_pic', 'g.present_price')
            ->where(['c.user_id' => $user_id, 'c.is_fresh' => $is_fresh])
            ->get();
        $cart_money = 0;
        if (empty($cart_list)) {
            $cart_list = [];
        } else {
            foreach ($cart_list as $cart) {
                $cart_money += $cart->goods_num * $cart->present_price;
            }
        }
        return $this->success(['cart_list' => $cart_list]);
    }

    /**
     * 减少购物车商品
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function decInCart(Request $request)
    {
        $user = Auth::user();
        $user_id = $user->id;
        $id = $request->input("id", 0);
        if ($id <= 0) {
            return $this->failed("参数错误");
        }
        $goods = DB::table('goods')->where(['id' => $id, 'status' => 1])->first();
        if (empty($goods)) {
            return $this->failed("参数错误");
        }
        $goods_is_exist = DB::table('shopping_cart')->where(['user_id' => $user_id, 'goods_id' => $id])->first();
        if (empty($goods_is_exist) || $goods_is_exist->goods_num <= 1) {
            return $this->failed("参数错误");
        }
        $res = DB::table('shopping_cart')->where(['id' => $goods_is_exist->id])->decrement('goods_num');
        if (empty($res)) {
            return $this->failed("减少商品失败");
        }
        return $this->success("减少商品成功");
    }

    /**
     * 删除购物车商品
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function deleteInCart(Request $request)
    {
        $user = Auth::user();
        $user_id = $user->id;
        $id = $request->input("id", 0);
        if ($id <= 0) {
            return $this->failed("参数错误");
        }
        $goods = DB::table('goods')->where(['id' => $id, 'status' => 1])->first();
        if (empty($goods)) {
            return $this->failed("参数错误");
        }
        $goods_is_exist = DB::table('shopping_cart')->where(['user_id' => $user_id, 'goods_id' => $id])->first();
        if (empty($goods_is_exist)) {
            return $this->failed("参数错误");
        }
        $res = DB::table('shopping_cart')->where(['id' => $goods_is_exist->id])->delete();
        if (empty($res)) {
            return $this->failed("删除商品失败");
        }
        return $this->success("删除商品成功");
    }

    /**
     * 获取城市
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function getCities()
    {
        $cities = DB::table('city')->select('id', 'name')->where(['status' => 1])->get();
        if (empty($cities)) {
            $cities = [];
        }
        return $this->success(['cities' => $cities]);
    }

    /**
     * 获取自提点
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getPickupSites(Request $request)
    {
        $city_id = $request->input("city_id", 1); //默认为 重庆
        if ($city_id <= 0) {
            return $this->failed("参数错误");
        }
        $city = DB::table('city')->where(['id' => $city_id, 'status' => 1])->first();
        if (empty($city)) {
            return $this->failed("参数错误");
        }
        $sites = DB::table('pickup_site')->select('id', 'name', 'addr')->where(['city_id' => $city_id, 'status' => 1])->get();
        $sites = empty($sites) ? [] : $sites;
        return $this->success(['sites' => $sites]);
    }


    /**
     * 确认订单
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function confirmOrder(Request $request)
    {
        $user = Auth::user();
        $user_id = $user->id;
        $goods_ids = $request->input('goods_ids');
        $is_fresh = $request->input("is_fresh", 0);
        if (!in_array($is_fresh, array(0, 1))) {
            return $this->failed("参数错误");
        }
        if(!is_array($goods_ids)) {
            return $this->failed("参数错误");
        }
        $ids = [];
        foreach ($goods_ids as $goods_id) {
            $goods_id = (int)$goods_id;
            if (empty($goods_id)) {
                return $this->failed("参数错误");
            }
            $ids[] = $goods_id;
        }
        if (count($ids) > 100) {
            return $this->failed("订单商品超出限制");
        }
        $count = DB::table('shopping_cart')->where(['user_id' => $user_id, 'is_fresh' => $is_fresh])->whereIn('goods_id', $ids)->count();
        if ($count != count($ids)) {
            return $this->failed("参数错误");
        }

        $order_list = DB::table('shopping_cart AS c')
            ->leftJoin('goods AS g', 'g.id', '=', 'c.goods_id')
            ->select('c.goods_id', 'c.goods_num', 'g.title', 'g.main_pic', 'g.present_price')
            ->where(['c.user_id' => $user_id, 'c.is_fresh' => $is_fresh])
            ->whereIn('c.goods_id', $ids)
            ->get();
        $order_money = 0;
        if (empty($order_list)) {
            $order_list = [];
        } else {
            foreach ($order_list as $cart) {
                $order_money += $cart->goods_num * $cart->present_price;
            }
        }
        return $this->success(['order_list' => $order_list, 'order_money' => number_format($order_money, 2, ".", ""), 'is_fresh' => $is_fresh]);
    }

    /**
     * 提交订单
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function submitOrder(Request $request)
    {
        $user = Auth::user();
        $user_id = $user->id;
        $goods_ids = $request->input('goods_ids');
        $is_fresh = $request->input("is_fresh", 0);
        $site_id = $request->input("site_id", 0);
        $code = $request->input("code");

        if (!in_array($is_fresh, array(0, 1))) {
            return $this->failed("参数错误");
        }
        if(!is_array($goods_ids)) {
            return $this->failed("参数错误");
        }
        if (empty($site_id)) {
            return $this->failed("请选择自提点");
        }
        if (empty($code)) {
            return $this->failed("参数错误");
        }
        $ids = [];
        foreach ($goods_ids as $goods_id) {
            $goods_id = (int)$goods_id;
            if (empty($goods_id)) {
                return $this->failed("参数错误");
            }
            $ids[] = $goods_ids;
        }
        if (count($ids) > 100) {
            return $this->failed("订单商品超出限制");
        }


        $count = DB::table('shopping_cart')->where(['user_id' => $user_id, 'is_fresh' => $is_fresh])->whereIn('goods_id', $ids)->count();
        if ($count != count($ids)) {
            return $this->failed("购物车商品不存在");
        }

        $site = DB::table('pickup_site')->where(['id' => $site_id, 'status' => 1])->first();
        if (empty($site)) {
            return $this->failed("参数错误");
        }

        //获取openid
        $wechat_config = config('pay.wechat');
        $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$wechat_config['miniapp_id']}&secret={$wechat_config['miniapp_secret']}&js_code={$code}&grant_type=authorization_code";
        $client = new Client();
        $req = $client->request('GET', $url);

        $res =  json_decode($req->getBody()->getContents(), true);

        if (empty($res['openid'])) {
            return $this->failed("获取失败");
        }
        $openid = $res['openid'];

        //新增订单记录
        $order_no = $this->createUniqueOrderNo();
        $cart_list = DB::table('shopping_cart AS c')
            ->leftJoin('goods AS g', 'g.id', '=', 'c.goods_id')
            ->select('c.id', 'c.goods_id', 'c.goods_num', 'g.title', 'g.present_price')
            ->where(['c.user_id' => $user_id, 'c.is_fresh' => $is_fresh])
            ->whereIn('goods_id', $ids)
            ->get();
        $order_money = 0;
        $goods_num = 0;
        foreach ($cart_list as $cart) {
            $order_money += $cart->goods_num * $cart->present_price;
            $goods_num += $cart->goods_num;
        }

        $now_time = time();
        DB::beginTransaction();

        //新增订单记录
        $order_id = DB::table('shopping_order')->insertGetId([
            'order_no' => $order_no,
            'user_id' => $user_id,
            'site_id' => $site_id,
            'is_fresh' => $is_fresh,
            'goods_num' => $goods_num,
            'money' => $order_money,
            'status' => 1,
            'order_time' => $now_time,
            'auto_expire_time' => $now_time + 86400, //24小时
        ]);
        $order_goods = [];
        foreach ($cart_list as $cart) {
            $order_goods[] = [
                'order_id' => $order_id,
                'goods_id' => $cart->goods_id,
                'goods_num' => $cart->goods_num,
                'goods_price' => $cart->present_price
            ];
        }
        $order_item_res = DB::table('shopping_order_items')->insert($order_goods);
        //删除购物车记录
        $cart_res = DB::table('shopping_cart')->where(['user_id' => $user_id, 'is_fresh' => $is_fresh])->whereIn('goods_id', $ids)->delete();
        //新增支付记录
        $payment_res = DB::table('shopping_payment')->insert([
            'order_no' => $order_no,
            'user_id' => $user_id,
            'order_money' => $order_money,
            'status' => 1,
            'create_time' => $now_time
        ]);

        //调用微信支付
        $order = [
            'out_trade_no' => $order_no,
            'total_fee' => $order_money * 100,
            'body' => '小厘健康-支付',
            'openid' => $openid,
        ];
        $pay = Pay::wechat($wechat_config)->miniapp($order);
        if (empty($order_id) || empty($order_item_res) || empty($cart_res) || empty($payment_res) || empty($pay)) {
            DB::rollBack();
            return $this->failed("提交订单失败");
        }
        DB::commit();
        return $this->success(['payment' => $pay, 'order' => ['order_no' => $order_no]]);
    }


    /**
     * 生成唯一订单号
     *
     * @return string
     */
    private function createUniqueOrderNo()
    {
        $is_unique = false;
        while (!$is_unique) {
            $order_no = date("YmdHis") . rand(100000, 999999); //20位订单号：年月日时分秒 + 6位随机数
            $is_exist = DB::table('shopping_order')->where(['order_no' => $order_no])->first();
            if (empty($is_exist)) {
                $is_unique = true;
            }
        }
        return $order_no;
    }

    /**
     * 微信支付异步通知
     *
     * @return bool|\Symfony\Component\HttpFoundation\Response
     */
    public function wechatNotify()
    {
        $wechat_config = config('pay.wechat');
        $pay = Pay::wechat($wechat_config);
        try{
            $data = $pay->verify();
            Log::debug('Wechat notify', $data->all());
            if ($data->result_code == 'SUCCESS') {
                $order_no = $data->out_trade_no;
                $pay_money = $data->total_fee / 100;
                $payment = DB::table('shopping_payment')->where(['order_no' => $order_no])->first();
                if (empty($payment) || $payment->status != 1 || $payment->order_money != $pay_money) {
                    return "";
                }
                //验证成功，修改支付状态和订单状态
                $now_time = time();
                $today = date("Y-m-d");
                DB::beginTransaction();

                $payment_res = DB::table('shopping_payment')->where(['order_no' => $order_no])->update([
                    'status' => 2,
                    'pay_money' => $pay_money,
                    'pay_type' => 1,
                    'pay_order_id' => $data->transaction_id,
                    'pay_account' => $data->openid,
                    'pay_time' => $now_time

                ]);

                $order =  DB::table('shopping_order')->where(['order_no' => $order_no])->first();
                $order_data = ['status' => 2, 'pay_time' => $now_time, 'check_code' => createCheckCode()];
                if ($order->is_fresh == 1) {
                    if ($now_time > strtotime($today . " 12:00:00")) { //12点之前付款
                        $order_data['start_pick_time'] = strtotime($today . " 16:00:00");
                        $order_data['end_pick_time'] = strtotime($today . " 23:59:59");
                    } else {
                        $order_data['start_pick_time'] = strtotime($today . " 16:00:00 +1 day");
                        $order_data['end_pick_time'] = strtotime($today . " 23:59:59 +1 day");
                    }
                }
                $order_res = DB::table('shopping_order')->where(['order_no' => $order_no])->update($order_data);
                if (empty($payment_res) || empty($order_res)) {
                    DB::rollBack();
                } else {
                    DB::commit();
                }
            } else {
                return "";
            }

        } catch (\Exception $e) {
           Log::debug('Wechat notify', ['errorMsg' => $e->getMessage()]);
            return "";
        }

        return $pay->success();
    }

    /**
     * 订单查询
     *
     * @param Request $request
     * @return string
     */
    public function orderQuery(Request $request)
    {
        $user = Auth::user();
        $user_id = $user->id;
        $order_no = $request->input('order_no');

        //查询数据库，订单是否支付成功
        $order = DB::table('shopping_order')->where(['order_no' => $order_no, 'user_id' => $user_id])->first();
        if (empty($order)) {
            return $this->failed("参数错误");
        }
        if (!in_array($order['status'], array(1, 2))) {
            return $this->failed("参数错误");
        }
        if ($order['status'] == 1) {
            $wechat_config = config('pay.wechat');
            $pay = Pay::wechat($wechat_config);
            try{
                $data = $pay->find($order_no);
                Log::debug('Wechat notify', $data->all());
                if ($data->trade_state == 'SUCCESS') {
                    $pay_money = $data->total_fee / 100;
                    $payment = DB::table('shopping_payment')->where(['order_no' => $order_no])->first();
                    if (empty($payment) || $payment->status != 1 || $payment->order_money != $pay_money) {
                        return $this->failed("支付失败");
                    }
                    //验证成功，修改支付状态和订单状态
                    $now_time = time();
                    $today = date("Y-m-d");
                    DB::beginTransaction();

                    $payment_res = DB::table('shopping_payment')->where(['order_no' => $order_no])->update([
                        'status' => 2,
                        'pay_money' => $pay_money,
                        'pay_type' => 1,
                        'pay_order_id' => $data->transaction_id,
                        'pay_account' => $data->openid,
                        'pay_time' => $now_time

                    ]);

                    $order =  DB::table('shopping_order')->where(['order_no' => $order_no])->first();
                    $order_data = ['status' => 2, 'pay_time' => $now_time, 'check_code' => createCheckCode()];
                    if ($order->is_fresh == 1) {
                        if ($now_time > strtotime($today . " 12:00:00")) { //12点之前付款
                            $order_data['start_pick_time'] = strtotime($today . " 16:00:00");
                            $order_data['end_pick_time'] = strtotime($today . " 23:59:59");
                        } else {
                            $order_data['start_pick_time'] = strtotime($today . " 16:00:00 +1 day");
                            $order_data['end_pick_time'] = strtotime($today . " 23:59:59 +1 day");
                        }
                    }
                    $order_res = DB::table('shopping_order')->where(['order_no' => $order_no])->update($order_data);
                    if (empty($payment_res) || empty($order_res)) {
                        DB::rollBack();
                        return $this->failed("支付失败");
                    } else {
                        DB::commit();
                    }
                } else {
                    return $this->failed("支付失败");
                }

            } catch (\Exception $e) {
                Log::debug('Wechat notify', ['errorMsg' => $e->getMessage()]);
                return $this->failed("支付失败");
            }
        }
        return $this->success("支付成功");
    }
}
